/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "S_Scene.h"

#include <time.h>
#include <几何图形/图形相交.h>
#include <S_键值序列容器.h>


#include "拾取.h"

#include "底层绘图/intern/绘图框架.h"
#include "底层绘图/底层绘图框架.h"
#include "底层绘图/S_纹理.h"
#include "纹理/纹理.h"
#include "面/面.h"
#include "物体/S_摄像机.h"
#include "场景/场景.h"

#include "core/引擎配置.h"

#include "matXX.h"

#include <ppl.h>



static double dur;
static clock_t start, end;



S_Scene::S_Scene(uint32 id_name) :S_Object(E_物体类型::t_场景, id_name), m_重新录制绘图命令(true) {
	m_帧 = 0;
	start = clock();
	mf_渲染前Update = 0;

	//m_拾取树 = f_空间划分_create球形八叉树(0.1);


	//构建光追后端
	m_光追后端 = nullptr;
	
	m_矩形区域光几何ID = S_Object::m_ID生成器.f_Gen();
	m_圆形区域光几何ID = S_Object::m_ID生成器.f_Gen();


	m_光追顶层加速结构 = {};
	m_光追网格对象 = {};


	m_天空 = nullptr;
	m_天空默认材质 = nullptr;

	m_摆 = f_time_创建摆(30);
}

S_Scene::~S_Scene() {
	mf_渲染前Update = 0;

	m_物体.clear();
	m_物体set.clear();

	//f_空间划分_destroy球形八叉树(m_拾取树);

	f_time_销毁摆(m_摆);
}

void S_Scene::f_Update(S_摄像机* camera) {

	if (camera && camera->m_isUpdate) {
		camera->f_Update(nullptr);

		if (m_天空) {
			m_天空->f_set缩放(_Vec3(camera->m_近远端.y));
			m_天空->f_Update(nullptr, nullptr);
		}
	}


	if(f_time_摆(m_摆) == false) return;

	for (auto& e : m_更新回调) {
		if(e->mf_更新前) e->mf_更新前(this);
	}

	for (auto& e : m_物体) {
		e->f_Update(nullptr, nullptr);
	}

	for (auto& e : m_物体set) {
		if(!e->m_父对象)
			e->f_Update(nullptr, nullptr);
	}

	if (m_重新录制光追灯光) {
		f_scene_更新光追灯光(this);
	}
	
	if (mf_渲染前Update) {
		mf_渲染前Update((S_结构指针)this);
	}
	//更新动画
	S_物体::g_更新曲线关键帧 = false;

	if (m_光追后端) {
		//f_ob_更新光追底层加速结构(*m_光追后端->m_Ctx);
	}
	
	for (auto& e : m_更新回调) {
		if(e->mf_更新后) e->mf_更新后(this);
	}

}

void S_Scene::f_Render(S_摄像机* camera, const vec2& size, const vec2& offset, uint32 物体组) {
	S_Viewport	视口 = { offset.x, offset.y, size.x, size.y, 0.0f, 1.0f};
	S_Rect2D	裁剪 = { _iVec2(offset), uvec2{uint32(size.x), uint32(size.y)} + _uVec2(offset) };
	
	m_渲染参数.m_视图投影矩阵 = camera->m_投影矩阵;
	m_渲染参数.m_视口 = &视口;
	m_渲染参数.m_裁剪 = &裁剪;


	if (f_buf_getGlobal().g_全局模型纹理槽.m_槽数量 != 1) {
		f_buf_getGlobal().g_全局模型纹理槽.m_纹理信息 = (void**)realloc(f_buf_getGlobal().g_全局模型纹理槽.m_绑定位置, 1 * sizeof(void*));
		f_buf_getGlobal().g_全局模型纹理槽.m_绑定位置 = (uint32*)realloc(f_buf_getGlobal().g_全局模型纹理槽.m_绑定位置, 1 * sizeof(uint32*));
		f_buf_getGlobal().g_全局模型纹理槽.m_绑定数量 = (uint32*)realloc(f_buf_getGlobal().g_全局模型纹理槽.m_绑定数量, 1 * sizeof(uint32*));

		f_buf_getGlobal().g_全局模型纹理槽.m_槽数量 = 1;
	}

	f_buf_getGlobal().g_全局模型纹理槽.m_纹理信息[0] = f_scene_get纹理集(this);
	f_buf_getGlobal().g_全局模型纹理槽.m_绑定数量[0] = f_scene_get纹理集数量(this);
	f_buf_getGlobal().g_全局模型纹理槽.m_绑定位置[0] = DEF_TasterTexturesBindID_rgba8;

	*f_buf_全局GPU参数指针_ptr(f_buf_getGlobal().g_全局绑定参数) = f_df_全局GPU参数();

	//return;
	if (物体组 & 1 << 1) {
		for (auto& e : m_物体) {
			e->f_绘制(m_渲染参数);
		}
	}

	if (物体组 & 1) {
		for (auto& e : m_物体set) {
			if (!e->m_父对象) e->f_绘制(m_渲染参数);
		}
	}
	
	return;
}

void S_Scene::f_Ray准备渲染(S_摄像机* camera, GLSL_RenderFrame& 帧渲染参数, S_纹理& tex, S_渲染世界* 世界, uint32 采样) {

	if (m_光追后端->m_重新编译线管) {
		m_光追后端->f_重构材质线管();
		m_光追后端->m_重新编译线管 = false;
	}


//#pragma omp parallel sections
	{
//#pragma omp section
		{
			
		}
//#pragma omp section
		{
			//if (m_重新录制绘图命令) {
			//	m_光追后端->f_清除几何加速结构();
			//
			//	uint32 num = m_物体set.size();
			//	std::cout << "开始更新光追底层加速结构" << std::endl;
			//	std::atomic_uint 完成数量 = 0;
			//	for (auto& e : m_物体set) {
			//		switch (e->m_Type) {
			//			case E_物体类型::t_区域光:
			//			case E_物体类型::t_区域光_圆形:
			//			case E_物体类型::t_区域光_方形:
			//			case E_物体类型::t_多边形:
			//			case E_物体类型::t_网格物体:
			//				f_构建底层光追加速结构(e);
			//				++完成数量;
			//				std::cout << "光追底层加速结构构建完成:" << m_物体set.size() << "/" << 完成数量.load() << std::endl;
			//				break;
			//			default:
			//				break;
			//		}
			//	}
			//
			//	m_矩形区域光几何ID = S_全局缓存::m_方形区域光物体网格->m_光追网格ID;
			//	m_圆形区域光几何ID = S_全局缓存::m_圆形区域光物体网格->m_光追网格ID;
			//	
			//	m_光追后端->f_添加底层加速结构(S_全局缓存::m_方形区域光物体网格, m_矩形区域光几何ID, E_物体类型::t_区域光_方形, 0);
			//	m_光追后端->f_添加底层加速结构(S_全局缓存::m_圆形区域光物体网格, m_圆形区域光几何ID, E_物体类型::t_区域光_圆形, 0);
			//
			//
			//	m_光追后端->f_重置渲染帧记录();
			//	m_重新录制绘图命令 = false;
			//}
			//
			//if (m_重新录制光追灯光) {
			//	uint32 id = 0;
			//	std::vector<S_LigthParallel> 平行光参数组(m_灯光.size());
			//	for (auto& e : m_灯光) {
			//		平行光参数组[id] = *f_ob_fromParallelLigth(e);
			//	}
			//	m_光追后端->f_填充平行光参数(平行光参数组);
			//	m_重新录制光追灯光 = false;
			//}
			//
			//uint32 id = 0;
			//for (auto& e : m_物体set) {
			//	f_构建顶层光追加速结构(e, id);
			//}
			//m_光追后端->f_构建顶层加速结构(id);
		}
	}
	
	//m_重新录制绘图命令;
	//uint32 场景网格组数量 = f_ob_get光追加速结构描述集数量(世界->m_光追描述集);


	帧渲染参数.m_Frame = m_光追后端->f_递增渲染帧记录();
	(*m_光追后端->m_mapPtr_渲染帧数据) = 帧渲染参数;
	(*m_光追后端->m_mapPtr_渲染帧数据).m_world_ShaderID = m_光追后端->m_渲染配置.环境材质ID;
	(*m_光追后端->m_mapPtr_渲染帧数据).m_PointLightNum = m_光追后端->m_渲染配置.点光源数量;
	(*m_光追后端->m_mapPtr_渲染帧数据).m_ViewSize = 帧渲染参数.m_ViewSize;
	

	f_buf_copy板载缓存(m_光追后端->m_投影矩阵, camera->m_投影矩阵);
	
	*f_buf_全局GPU参数指针_ptr(f_buf_getGlobal().g_全局绑定参数) = f_df_全局GPU参数();

	
	f_纹理集_刷新所有纹理信息(世界->m_输出纹理);
	f_纹理槽_设置纹理集(世界->m_输出纹理槽, 世界->m_输出纹理, 0, DEF_BINDING_RayTexturesWriteLayers);

	
	(*m_光追后端->m_mapPtr_渲染帧数据).m_Address_RtOb = f_buf_getAddress2(世界->m_物体指针);

	m_光追后端->m_参数布局.m_参数槽[0] = 世界->m_光追描述集;
	m_光追后端->m_参数布局.m_参数类型[0] = E_板载缓存类型::e_光追BVH;
	m_光追后端->m_参数布局.m_绑定位置[0] = 0;
	m_光追后端->m_参数布局.m_绑定数量[0] = f_ob_get光追加速结构描述集数量(世界->m_光追描述集);
	
	
	
	m_光追后端->m_参数布局.m_参数槽[1] = &tex;
	m_光追后端->m_参数布局.m_参数类型[1] = E_板载缓存类型::e_IMAGE;
	m_光追后端->m_参数布局.m_绑定位置[1] = DEF_BINDING_Render_Image;
	m_光追后端->m_参数布局.m_绑定数量[1] = 1;
	
	m_光追后端->m_参数布局.m_参数槽[2] = m_光追后端->m_投影矩阵;
	m_光追后端->m_参数布局.m_参数类型[2] = E_板载缓存类型::e_SSBO;
	m_光追后端->m_参数布局.m_绑定位置[2] = DEF_BINDING_Render_Camera;
	m_光追后端->m_参数布局.m_绑定数量[2] = 1;
	
	m_光追后端->m_参数布局.m_参数槽[3] = f_buf_getGlobal().m_场景物体网格属性;
	m_光追后端->m_参数布局.m_参数类型[3] = E_板载缓存类型::e_SSBO;
	m_光追后端->m_参数布局.m_绑定位置[3] = DEF_ObMeshBindID;
	m_光追后端->m_参数布局.m_绑定数量[3] = 1;
	
	m_光追后端->m_参数布局.m_参数槽[4] = f_buf_getGlobal().g_材质;
	m_光追后端->m_参数布局.m_参数类型[4] = E_板载缓存类型::e_SSBO;
	m_光追后端->m_参数布局.m_绑定位置[4] = DEF_MaterialsBindID;
	m_光追后端->m_参数布局.m_绑定数量[4] = 1;
	
	
	m_光追后端->m_参数布局.m_参数槽[5] = m_光追后端->m_帧渲染信息;
	m_光追后端->m_参数布局.m_参数类型[5] = E_板载缓存类型::e_UBO;
	m_光追后端->m_参数布局.m_绑定位置[5] = DEF_RenderFrameBindID;
	m_光追后端->m_参数布局.m_绑定数量[5] = 1;
	
	m_光追后端->m_参数布局.m_参数槽[6] = f_buf_getGlobal().m_平行光缓冲区;
	m_光追后端->m_参数布局.m_参数类型[6] = E_板载缓存类型::e_SSBO;
	m_光追后端->m_参数布局.m_绑定位置[6] = DEF_ParallelLightBindID;
	m_光追后端->m_参数布局.m_绑定数量[6] = 1;
	
	m_光追后端->m_参数布局.m_参数槽[7] = m_光追后端->f_get纹理(E_纹理分组类型::e_2D纹理);
	m_光追后端->m_参数布局.m_参数类型[7] = E_板载缓存类型::e_SAMPLER_Array;
	m_光追后端->m_参数布局.m_绑定位置[7] = DEF_TexturesBindID;
	m_光追后端->m_参数布局.m_绑定数量[7] = m_光追后端->f_get纹理数量(E_纹理分组类型::e_2D纹理);
	
	m_光追后端->m_参数布局.m_参数槽[8] = f_buf_getGlobal().m_几何属性;
	m_光追后端->m_参数布局.m_参数类型[8] = E_板载缓存类型::e_SSBO;
	m_光追后端->m_参数布局.m_绑定位置[8] = DEF_BINDING_Render_Geom;
	m_光追后端->m_参数布局.m_绑定数量[8] = 1;
	
	m_光追后端->m_参数布局.m_参数槽[9] = f_buf_getGlobal().m_全局绑定参数指针;
	m_光追后端->m_参数布局.m_参数类型[9] = E_板载缓存类型::e_SSBO;
	m_光追后端->m_参数布局.m_绑定位置[9] = DEF_BINDING_Render_GlobalParam;
	m_光追后端->m_参数布局.m_绑定数量[9] = 1;
	
	m_光追后端->m_参数布局.m_参数槽[10] = m_光追后端->f_get纹理(E_纹理分组类型::e_字符纹理);
	m_光追后端->m_参数布局.m_参数类型[10] = E_板载缓存类型::e_SAMPLER_Array;
	m_光追后端->m_参数布局.m_绑定位置[10] = DEF_BINDING_RayArrayTexturesBindID;
	m_光追后端->m_参数布局.m_绑定数量[10] = m_光追后端->f_get纹理数量(E_纹理分组类型::e_字符纹理);
	
	m_光追后端->m_参数布局.m_纹理槽 = &世界->m_输出纹理槽;
	
	f_df_upGPU参数(m_光追后端->m_Ctx->m_逻辑设备.设备, m_光追后端->m_GPU参数设置, m_光追后端->m_参数布局, false);
	

	if (采样) {
		m_光追后端->f_Rander(帧渲染参数, 采样);
	}
	else {
		m_光追后端->f_Rander(帧渲染参数);
	}
}

void S_Scene::f_Ray渲染(GLSL_RenderFrame& 帧渲染参数, uint32 采样) {
	if (采样) {
		m_光追后端->f_Rander(帧渲染参数, 采样);
	}
	else {
		m_光追后端->f_Rander(帧渲染参数);
	}
}

void S_Scene::f_渲染世界() {
	f_ob_绘制单个元素(m_天空, m_渲染参数, 0, false);
}

bool S_Scene::f_载入纹理() {
	m_需要要加载纹理 = 0;

	if (m_光追后端) {
		S_光追后端::g_资源分配内存锁.lock();
		
		m_需要要加载纹理 = m_光追后端->m_待加载纹理列队.size();
		if (m_需要要加载纹理) {
			for (auto& tex : m_光追后端->m_待加载纹理列队) {
				if (tex.m_纹理对象->m_像素) {
					f_tex_加载图像到GPU(tex, m_光追后端->m_渲染命令缓存);
	
					free(tex.m_纹理对象->m_像素);
					tex.m_纹理对象->m_像素 = nullptr;
					--m_需要要加载纹理;
	
					m_光追后端->f_set纹理(tex.m_纹理对象);
					std::cout << "载入纹理到渲染器:" << tex.m_纹理对象->m_加载的文件路径 << std::endl;
				}
			}
			m_光追后端->m_待加载纹理列队.clear();
	
			for (auto& e : m_光追后端->G纹理) {
				m_光追后端->f_set纹理((S_纹理*)e.m_Ptr);
			}
		}
	
	
		if (m_光追后端->m_重新设置内部纹理传入参数) {
			for (auto& e : m_光追后端->G字符纹理) {
				m_光追后端->f_set纹理((S_纹理*)e.m_Ptr, E_纹理分组类型::e_字符纹理);
			}
			//for (auto& e : m_光追后端->G字符纹理) {
			//	m_光追后端->f_set纹理((S_纹理*)e.m_Ptr, S_光追后端::E_纹理分组类型::e_字符纹理);
			//}
			m_光追后端->f_刷新纹理GPU布局();
		}
	
		S_光追后端::g_资源分配内存锁.unlock();
	}

	if (m_需要要加载纹理 > 0) return false;
	return true;
}


void S_Scene::f_构建底层光追加速结构(S_物体* ob) {
	if (ob->m_渲染) {
		switch (ob->m_Type) {
		case E_物体类型::t_多边形:
		case E_物体类型::t_网格物体: {
			auto me = f_ob_getMesh(ob, E_物体网格元素类型::e_MT_光照);
			//auto me = f_ob_fromMesh(ob, E_物体网格元素类型::e_MT_面);
			
			if(me->m_索引->m_Mem.m_数量 && me->m_顶点->m_Mem.m_数量) {
				m_光追后端->f_添加底层加速结构(me, me->m_光追网格ID, ob->m_Type, 0);

				me->m_更新光追加速结构 = false;
			}
			break;
		}
			 

		case E_物体类型::t_区域光_方形: {
			S_Mesh* me = f_buf_getGlobal().m_方形区域光物体网格;
			
			f_mesh_构建网格属性参数(ob, me, DEF_ObType_Ligth);
			break;
		}

		case E_物体类型::t_区域光_圆形: {
			S_Mesh* me = f_buf_getGlobal().m_方形区域光物体网格;
			
			f_mesh_构建网格属性参数(ob, me, DEF_ObType_Ligth);
			break;
		}

		default:
			break;
		}

		for (auto& ob : ob->m_子物体) {
			f_构建底层光追加速结构(static_cast<S_物体*>(ob));
		}
	}
}
 
void S_Scene::f_构建顶层光追加速结构(S_物体* ob, uint32& offset) {
	switch (ob->m_Type) {
	case E_物体类型::t_多边形: 
	case E_物体类型::t_网格物体: {
		
		if (ob->m_视口显示模式 & m_光追后端->g_物体全局显示模式) {
			S_Mesh* me = f_ob_getMesh(ob, E_物体网格元素类型::e_MT_光照);
			
			uint32 实例数量 = ob->m_变换矩阵.m_Mem.m_数量;
			if (me->m_索引->m_Mem.m_数量) {
				auto* mat = f_buf_Mat44_ptr(ob->m_变换矩阵);

				static uint32 空实例材质 = 0;
				auto* 实例材质 = &空实例材质;
				bool 使用实例材质;
				if (ob->m_实例材质ID.size() >= 实例数量) {
					实例材质 = ob->m_实例材质ID.data();
					使用实例材质 = true;
				}
				else {
					使用实例材质 = false;
				}

				m_光追后端->f_预分配实例变换(实例数量);
				for (int64 i = 0; i < 实例数量; ++i) {
					if (m_光追后端->f_更新实例变换(
						*me->m_底层光追加速结构
						, f_mat3x4_转换(mat[i])
						, offset + i
						, me->m_光追网格ID
						, 使用实例材质 ? 实例材质[i] : 0
						, 0xff
						, 实例数量
						)) {
					}
				}



				offset += 实例数量;
			}
		}
		break;
	}
	
	case E_物体类型::t_区域光: {
		uint32 几何ID = ob->m_ID;
		auto* mat = f_buf_Mat44_ptr(ob->m_变换矩阵);

		m_光追后端->f_更新实例变换(
			*f_buf_getGlobal().m_方形区域光物体网格->m_底层光追加速结构
			, f_mat3x4_转换(*mat)
			, offset
			, m_矩形区域光几何ID
			, ob->m_ID
			
			, 1
			, 0xff);

		S_Mesh* me = f_buf_getGlobal().m_方形区域光物体网格;
		
		f_mesh_构建网格属性参数(ob, me, DEF_ObType_Ligth);
		++offset;
		break;
	}

	case E_物体类型::t_包: {
		if(!ob->m_变换矩阵.m_Mem.m_数量) break;
		uint32 几何ID = ob->m_ID;
		auto* mat = f_buf_Mat44_ptr(ob->m_变换矩阵);
		for (uint32 i = 0; i < ob->m_变换矩阵.m_Mem.m_数量; ++i) {
			switch (static_cast<S_物体*>(ob->m_子物体[i])->m_Type) {
			case E_物体类型::t_区域光_方形: 几何ID = m_矩形区域光几何ID; break;
			case E_物体类型::t_区域光_圆形: 几何ID = m_圆形区域光几何ID; break;
			default:
				continue;
			}
			m_光追后端->f_更新实例变换(
				*f_buf_getGlobal().m_方形区域光物体网格->m_底层光追加速结构
				, f_mat3x4_转换(mat[i])
				, offset
				, 几何ID
				, ob->m_子物体[i]->m_ID
				, 1
				, 0xff);

			S_Mesh* me = f_buf_getGlobal().m_方形区域光物体网格;
			
			f_mesh_构建网格属性参数(ob, me, DEF_ObType_Ligth);
			++offset;
		}
		break;
	}
	
	default:
		break;
	}

	for (auto& ob : ob->m_子物体) {
		f_构建顶层光追加速结构(static_cast<S_物体*>(ob), offset);
	}
}









void S_Scene::f_add物体(S_物体* ob) {
	switch (ob->m_Type) {
	case E_物体类型::t_多边形:
	case E_物体类型::t_网格物体:
	case E_物体类型::t_空:
		m_物体.push_back(ob);
		
		ob->m_isUpdate = true;
		ob->m_UpdateGPU参数布局 = true;
	default:
		break;
	}
}

void S_Scene::f_add物体(const std::vector<S_物体*> obs, E_场景物体容器类型 type) {
	for (auto& ob : obs) {
		switch (ob->m_Type) {
			case E_物体类型::t_区域光:
			case E_物体类型::t_点光源:
			case E_物体类型::t_聚光灯:
			case E_物体类型::t_平行光: {
				if (m_灯光.find(ob) == m_灯光.end()) {
					m_灯光.insert(ob);
					m_重新录制光追灯光 = true;
				}
				//break;
			}

			case E_物体类型::t_灯光:
			case E_物体类型::t_粒子系统:
			case E_物体类型::t_网格物体:
			case E_物体类型::t_多边形:
			case E_物体类型::t_空间曲线:
				m_重新录制绘图命令 = true;

			case E_物体类型::t_包:
			case E_物体类型::t_物体包:
			case E_物体类型::t_空:
			case E_物体类型::t_点:
			case E_物体类型::t_虚拟体:
			case E_物体类型::t_标注:


			case E_物体类型::t_骨架:
			case E_物体类型::t_骨骼:
				switch (type) {
					case e_链表:
						m_物体.push_back(ob);
						break;
					case e_数组:
						break;
					case e_映射:
						break;
					case e_集合:
						m_物体set.insert(ob);
						break;
					default:
						break;
				}
				
				break;

			default:
				break;
		}


		ob->m_isUpdate = true;
		ob->m_UpdateGPU参数布局 = true;
	}

	

	
}

void S_Scene::f_remove物体(S_物体* ob, E_场景物体容器类型 type) {
	switch (type) {
	case e_链表:
		break;
	case e_数组:
		break;
	case e_映射:
		break;
	case e_集合:
		if (m_物体set.find(ob) != m_物体set.end()) {
			switch (ob->m_Type) {
			case E_物体类型::t_网格物体:
			case E_物体类型::t_多边形:
				//m_几何ID生成器.f_Move(ob->m_ID);
				//S_物体::g_包围盒物体->m_变换矩阵块 = f_buf_gfree(S_物体::g_包围盒物体->m_变换矩阵, 0);
				//S_物体::g_包围盒物体->m_实例数量 = m_物体set.size();
			default:
				break;
			}

			m_重新录制绘图命令 = true;
			m_物体set.erase(ob);
		}
		break;
	default:
		break;
	}
}

void S_Scene::f_remove物体(const std::vector<S_物体*>& obs, E_场景物体容器类型 type) {
	switch (type) {
	case e_链表:
		break;
	case e_数组:
		break;
	case e_映射:
		break;
	case e_集合:
		for (auto& ob : obs) {
			switch (ob->m_Type) {
				case E_物体类型::t_点光源: break;
				case E_物体类型::t_聚光灯: break;
				case E_物体类型::t_区域光: break;
				case E_物体类型::t_平行光: {
					if (m_灯光.find(ob) != m_灯光.end()) {
						m_灯光.erase(ob);
						m_重新录制绘图命令 = true;
					}
					//break;
				}
			

				default:
					if (m_物体set.find(ob) != m_物体set.end()) {
						m_物体set.erase(ob);
						m_重新录制绘图命令 = true;
					}
					break;
			}
		}
		
		break;
	default:
		break;
	}
}

vec3 S_Scene::f_get屏幕坐标到空间(S_摄像机* camera, const vec3& pos, const S_Rect2Df& view) {
	vec3 coord = f_UpProject还原空间顶点(pos, *(Mat44f*)&camera->m_相机投影矩阵, *(Mat44f*)&camera->m_相机视图矩阵, view);
	return coord;
}

/*std::vector<S_物体*> S_Scene::f_拾取(const vec3& s, const vec3& e, bool 是否多个) {
	std::vector<S_物体*> pickObjs;
	for (auto& obj : m_物体set) {
		if (obj->m_可拾取) {
			auto* m = f_ob_fromMesh(obj);
			//f_surface_射线相交()
			if (m) m->f_拾取(s, e);
		}
	}
	return pickObjs;
}*/

void S_Scene::f_构建物体空间树(float32 最小单元) {
	f_空间划分_set叉树空间大小(m_拾取树, 1000000.0, {});

	f_空间划分_remove所有子集(m_拾取树);

	for (auto& obj : m_物体set) {
		S_Sphere c = f_ob_get范围(obj);
		auto* 单元 = f_空间划分_add子集(m_拾取树, c.pos, DEF_Max(最小单元, c.radius));
		if (单元->m_数据 == nullptr) {
			单元->m_数据 = new std::vector<S_物体*>();
		}
		((std::vector<S_物体*>*)单元->m_数据)->push_back(obj);
	}

}









S_物体拾取信息 f_scene_射线拾取物体(
									S_物体* ob
									, const vec3& s
									, const vec3& dir
									, S_Mesh* mesh
									, Mat44f* 父级变换
									, const S_摄像机& camera
									, const S_Rect2Df& rect
									, const vec2& 屏幕坐标
									, uint8 网格层
									, const vec3& 相机位置) {

	static uint32 g网格数据层索引[3] = { E_物体网格元素类型::e_MT_框, E_物体网格元素类型::e_MT_面, E_物体网格元素类型::e_MT_边 };
	
	
	S_物体拾取信息 物体拾取信息 = { nullptr, -1, 100000000, 1e+7 , 0};
	if (!ob->m_可拾取) return 物体拾取信息;


	float32 当前拾取距离 = 100000000;
	

	Mat44f* 当前矩阵prt = 父级变换;
	if (ob->m_变换矩阵.m_Mem.m_数量) {
		当前矩阵prt = f_buf_Mat44_ptr(ob->m_变换矩阵);
	}
	else {
		goto To_子集;
	}

	


	if (!mesh) {
		auto me = f_ob_getMesh(ob, 网格层);
		if (me) mesh = me;
	}

	if (mesh && ob->m_显示) {
		Mat44f mat[4] = { 当前矩阵prt[ob->m_实例ID], camera.m_相机逆矩阵 };

		auto 包围盒 = f_ob_get包围盒(mat[0], mesh->f_getBound());

		float32 线拾取距离 = vec_len(相机位置 - 包围盒.pos) * 0.02;
		float32 距离 = f_graph_点到直线距离(s, dir, 包围盒.pos);
		vec3 size = 包围盒.size;
		

		if (ob->m_是否实例) {
			size = { 1,1,1 };
		}
		else {
			float32 包围盒半径 = vec_Max(size);
			switch (ob->m_Type) {
				case E_物体类型::t_灯光:
				case E_物体类型::t_包:
				case E_物体类型::t_区域光:
				case E_物体类型::t_平行光:
				case E_物体类型::t_点光源:
					break;
				default:
					if (距离 >= 包围盒半径 * 1.3 + 线拾取距离) {
						goto To_子集;
					}
					break;
			}
		}
		

		float32* 独立缩放 = nullptr;

		switch (ob->m_Type) {
			case E_物体类型::t_骨节:
			case E_物体类型::t_骨架:
			case E_物体类型::t_骨骼: 
				S_面拾取 拾取信息;
				if (mesh->m_索引->m_Mem.m_数量 > 10000) {
					拾取信息 = f_surface_Gpu射线拾取面(mesh, s, dir, mat, 相机位置);
				}
				else {
					拾取信息 = f_surface_射线面相交(mesh, mat, s, dir, 相机位置);
				}

				if (拾取信息.面索引 >= 0) {
					S_物体拾取信息 新拾取;
					
					新拾取.平面距离 = 6;
					新拾取.实例ID = ob->m_实例ID;
					新拾取.物体 = ob;
					//if (camera.m_投影模式 == E_投影模式::e_正交) {
					//	新拾取.相交深度 = length(拾取信息.相交坐标 - 相机位置);
					//}
					//else {
						新拾取.相交深度 = 拾取信息.相交宽度;
					//}
					f_scene_对比拾取信息(物体拾取信息, 新拾取);
				}
				break;


			
			case E_物体类型::t_多边形:
			case E_物体类型::t_网格物体:
				if (ob->m_变换矩阵.m_Mem.m_数量 > 1) break;
			case E_物体类型::t_实例: {
				
				switch (网格层) {
					case E_物体网格元素类型::e_MT_面: {
						S_面拾取 拾取信息;
						if (mesh->m_索引->m_Mem.m_数量 > 10000) {
							拾取信息 = f_surface_Gpu射线拾取面(mesh, s, dir, mat, 相机位置);
						}
						else {
							拾取信息 = f_surface_射线面相交(mesh, mat, s, dir, 相机位置);
						}

						if (拾取信息.面索引 >= 0) {
							S_物体拾取信息 新拾取;
							新拾取.平面距离 = 6;
							新拾取.实例ID = ob->m_实例ID;
							新拾取.物体 = ob;
							//if (camera.m_投影模式 == E_投影模式::e_正交) {
							//	新拾取.相交深度 = length(拾取信息.相交坐标 - 相机位置);
							//}
							//else {
								新拾取.相交深度 = 拾取信息.相交宽度;
							//}
							f_scene_对比拾取信息(物体拾取信息, 新拾取);
						}
						break;
					}
					case E_物体网格元素类型::e_MT_边: {
						mat[0] = 当前矩阵prt[ob->m_实例ID];
						mat[1] = *(Mat44f*)&camera.m_相机投影矩阵;
						mat[2] = *(Mat44f*)&camera.m_相机视图矩阵;
						mat[3] = *(Mat44f*)&camera.m_相机逆矩阵;

						S_线拾取 拾取信息 = f_surface_屏幕拾取三角形边(mesh, mat, 屏幕坐标, rect, 28, ob->m_实例ID, true);

						S_物体拾取信息 新拾取;
						新拾取.相交深度 = length(拾取信息.交点 - 相机位置);
						新拾取.平面距离 = 拾取信息.相交宽度;
						新拾取.实例ID = ob->m_实例ID;
						新拾取.物体 = ob;
						新拾取.拾取模式 = 1;

						f_scene_对比拾取信息(物体拾取信息, 新拾取, 1);
						break;
					}
					case E_物体网格元素类型::e_MT_框: {
						S_线拾取 拾取信息 = f_surface_线段相交(mesh, mat, s, dir, 当前拾取距离, ob->m_实例ID);

						if (拾取信息.线索引 >= 0) {
							S_物体拾取信息 新拾取;
							新拾取.相交深度 = 拾取信息.相交点到起点距离;
							新拾取.平面距离 = 拾取信息.相交宽度;
							新拾取.实例ID = ob->m_实例ID;
							新拾取.物体 = ob;
							新拾取.拾取模式 = 1;

							f_scene_对比拾取信息(物体拾取信息, 新拾取);
						}
						break;
					}
					default:
						break;
				}
				break;
			}

			case E_物体类型::t_区域光_方形:
			case E_物体类型::t_区域光_圆形:
			case E_物体类型::t_平行光:
			case E_物体类型::t_聚光灯:
			case E_物体类型::t_区域光:
			case E_物体类型::t_点光源 :

			case E_物体类型::t_灯光:
			case E_物体类型::t_虚拟体: {
				//S_线拾取 拾取信息 = f_surface_线段相交(mesh, mat, s, dir, 当前拾取距离, ob->m_实例ID);

				mat[0] = 当前矩阵prt[ob->m_实例ID];
				mat[1] = *(Mat44f*)&camera.m_相机投影矩阵;
				mat[2] = *(Mat44f*)&camera.m_相机视图矩阵;
				mat[3] = *(Mat44f*)&camera.m_相机逆矩阵;

				S_线拾取 拾取信息 = f_surface_屏幕拾取线段(mesh, mat, 屏幕坐标, rect, 28, ob->m_实例ID);

				S_物体拾取信息 新拾取{};
				新拾取.相交深度 = length(拾取信息.交点 - 相机位置);
				新拾取.平面距离 = 拾取信息.相交宽度;
				新拾取.实例ID = ob->m_实例ID;
				新拾取.物体 = ob;
				新拾取.拾取模式 = 1;

				f_scene_对比拾取信息(物体拾取信息, 新拾取, 1);
				break;
			}
			case E_物体类型::t_线段: {
				break;
			}
			case E_物体类型::t_空间曲线: {
				mat[0] = 当前矩阵prt[ob->m_实例ID];
				mat[1] = *(Mat44f*)&camera.m_相机投影矩阵;
				mat[2] = *(Mat44f*)&camera.m_相机视图矩阵;

				vec3 拾取坐标;
				线拾取距离 = f_surface_屏幕拾取曲线(mesh, mat, 屏幕坐标, rect, 28, 拾取坐标);

				S_物体拾取信息 新拾取{};
				新拾取.相交深度 = length(拾取坐标 - 相机位置);
				
				新拾取.平面距离 = 线拾取距离;
				新拾取.实例ID = ob->m_实例ID;
				新拾取.物体 = ob;
				新拾取.拾取模式 = 1;

				f_scene_对比拾取信息(物体拾取信息, 新拾取, 1);
				break;
			}

			default:
				break;
		}
	}



	To_子集:
	uint32 num = ob->m_子物体.size();
	auto* obs = ob->m_子物体.data();

	
	uint32 网格层数量 = DEF_Min(3, ob->m_DataNum);
	for (uint32 i = 0; i < num; ++i) {
		S_物体拾取信息 子物体拾取;
		auto* ob = static_cast<S_物体*>(obs[i]);
		auto* me = mesh;

		switch (ob->m_Type) {
			case E_物体类型::t_线段: {
				for (uint32 k = 0; k < ob->m_DataNum; ++k) {
					auto* m = f_ob_getMesh(ob, k);
					子物体拾取 = f_scene_射线拾取物体(ob, s, dir, m, 当前矩阵prt, camera, rect, 屏幕坐标, g网格数据层索引[k], 相机位置);
					
					f_scene_对比拾取信息(物体拾取信息, 子物体拾取);
				}
				break;
			}
		
			case E_物体类型::t_骨节:
			case E_物体类型::t_骨架:
			case E_物体类型::t_骨骼: {
				子物体拾取 = f_scene_射线拾取物体(ob, s, dir, me, 当前矩阵prt, camera, rect, 屏幕坐标, 网格层, 相机位置);
				f_scene_对比拾取信息(物体拾取信息, 子物体拾取);
				break;
			}
			case E_物体类型::t_空间曲线: {
				子物体拾取 = f_scene_射线拾取物体(ob, s, dir, me, 当前矩阵prt, camera, rect, 屏幕坐标, 网格层, 相机位置);
				f_scene_对比拾取信息(物体拾取信息, 子物体拾取);
				break;
			}
		
			case E_物体类型::t_网格物体:
			case E_物体类型::t_多边形:
				网格层数量 = DEF_Min(3, ob->m_DataNum);
				me = nullptr;

			case E_物体类型::t_实例:
				//f_ob_get实例父对象()
			default: {
			
				for (uint32 k = 0; k < 网格层数量; ++k) {
					if (f_ob_显示模式是否开启(ob, g网格数据层索引[k])) {
						子物体拾取 = f_scene_射线拾取物体(ob, s, dir, me, 当前矩阵prt, camera, rect, 屏幕坐标, g网格数据层索引[k], 相机位置);
						
						f_scene_对比拾取信息(物体拾取信息, 子物体拾取);
					}
				}
				break;
			}
		}
	}

	if (物体拾取信息.物体 && (ob->m_Type == E_物体类型::t_物体包 || ob->m_Type == E_物体类型::t_骨架)) {
		物体拾取信息.物体 = ob;
	}else if (物体拾取信息.物体 && (ob->m_附属类型 == E_物体类型::t_物体包 || ob->m_附属类型 == E_物体类型::t_骨架)) {
		//物体拾取信息.物体 = ob;
	}


	return 物体拾取信息;
}

S_物体拾取信息 f_scene_射线拾取物体面(S_物体* ob, const vec3& s, const vec3& dir, S_Mesh* mesh, Mat44f* 父级变换, const S_摄像机& camera, uint8 网格层, const vec3& 相机位置) {
	
	S_物体拾取信息 物体拾取信息 = { nullptr, -1, 100000000, 1e+7, 0, 0 };
	uint32 实例数量 = ob->m_变换矩阵.m_Mem.m_数量;

	if (!ob->m_可拾取) return 物体拾取信息;


	Mat44f* 当前矩阵prt = 父级变换;
	if (实例数量) {
		当前矩阵prt = f_buf_Mat44_ptr(ob->m_变换矩阵);
	}



	if (!mesh) {
		auto me = f_ob_getMesh(ob, 网格层);
		if (me) mesh = me;
	}

	if (mesh && ob->m_显示 && 当前矩阵prt) {
		Mat44f mat[4] = { 当前矩阵prt[ob->m_实例ID], camera.m_相机逆矩阵 };

		auto 包围盒 = f_ob_get包围盒(mat[0], mesh->f_getBound());

		float32 线拾取距离 = vec_len(相机位置 - 包围盒.pos) * 0.02;
		float32 距离 = f_graph_点到直线距离(s, dir, 包围盒.pos);
		vec3 size = 包围盒.size;


		if (ob->m_是否实例) {
			size = { 1,1,1 };
		}
		else {
			float32 包围盒半径 = vec_Max(size);
			if (距离 >= 包围盒半径 * 1.3 + 线拾取距离) {
				goto To_子集;
			}
		}


		switch (ob->m_Type) {
			case E_物体类型::t_多边形:
			case E_物体类型::t_网格物体:
				if (实例数量 > 1 || ob->m_根实例) break;
			case E_物体类型::t_实例: {
				
				S_面拾取 拾取信息;
				if (mesh->m_索引->m_Mem.m_数量 > 10000) {
					拾取信息 = f_surface_Gpu射线拾取面(mesh, s, dir, mat, 相机位置);
				}
				else {
					拾取信息 = f_surface_射线面相交(mesh, mat, s, dir, 相机位置);
				}

				if (拾取信息.面索引 >= 0) {
					S_物体拾取信息 新拾取;
					新拾取.平面距离 = 6;
					新拾取.实例ID = ob->m_实例ID;
					新拾取.物体 = ob;
					新拾取.相交深度 = 拾取信息.相交宽度;

					f_scene_对比拾取信息(物体拾取信息, 新拾取);
				}
				break;
			}

			default:
				break;
		}
	}



To_子集:
	uint32 num = ob->m_子物体.size();
	auto* obs = ob->m_子物体.data();


	for (uint32 i = 0; i < num; ++i) {
		S_物体拾取信息 子物体拾取;
		auto* ob = static_cast<S_物体*>(obs[i]);
		auto* me = mesh;

		switch (ob->m_Type) {
			case E_物体类型::t_网格物体:
			case E_物体类型::t_多边形:
				me = nullptr;

			case E_物体类型::t_实例:
			default: {
				//if (f_ob_显示模式是否开启(ob, 网格层)) {
				//	子物体拾取 = f_scene_射线拾取物体面(ob, s, dir, me, 当前矩阵prt, camera, 网格层, 相机位置);
				//	f_scene_对比拾取信息(物体拾取信息, 子物体拾取);
				//}
				子物体拾取 = f_scene_射线拾取物体面(ob, s, dir, me, 当前矩阵prt, camera, 网格层, 相机位置);
				f_scene_对比拾取信息(物体拾取信息, 子物体拾取);
				break;
			}
		}
	}
	return 物体拾取信息;
}

S_物体拾取信息 f_scene_射线拾取物体AABB(S_物体* ob, const vec3& s, const vec3& dir, S_Mesh* mesh, Mat44f* mat) {
	S_物体拾取信息 物体拾取信息 = { nullptr, -1, 100000000 };

	uint32 num = ob->m_子物体.size();
	auto* obs = ob->m_子物体.data();
	for (uint32 i = 0; i < num; ++i) {

	}

	return S_物体拾取信息();
}

void f_scene_对比拾取信息(S_物体拾取信息& 当前拾取, S_物体拾取信息& 新拾取, uint8 新拾取线模式) {
	if (新拾取.物体) {
		uint32 都是线拾取 = 0;

		switch (新拾取.物体->m_Type) {
			case E_物体类型::t_线段:
			case E_物体类型::t_灯光:
			case E_物体类型::t_平行光:
			case E_物体类型::t_点光源:
			case E_物体类型::t_区域光:
			case E_物体类型::t_聚光灯:
			case E_物体类型::t_虚拟体:
			case E_物体类型::t_空间曲线: {
				都是线拾取 |= 1;
				break;
			}
			case E_物体类型::t_多边形:
			case E_物体类型::t_网格物体: {
				都是线拾取 |= 新拾取线模式;
				break;
			}
				
		}

		if (当前拾取.物体) {
			
			switch (当前拾取.物体->m_Type) {
				case E_物体类型::t_线段:
				case E_物体类型::t_灯光:
				case E_物体类型::t_平行光:
				case E_物体类型::t_点光源:
				case E_物体类型::t_区域光:
				case E_物体类型::t_聚光灯:
				case E_物体类型::t_虚拟体:
				case E_物体类型::t_空间曲线: {
					都是线拾取 |= 2;
					break;
				}
				case E_物体类型::t_多边形:
				case E_物体类型::t_网格物体: {
					都是线拾取 |= 当前拾取.拾取模式 << 1;
					break;
				}
			}


			
			switch (都是线拾取) {
				case 3: {
					if (新拾取.平面距离 < 当前拾取.平面距离) {
						当前拾取 = 新拾取;
					}
					break;
				}
				case 2: {
					if (新拾取.相交深度 < 当前拾取.相交深度 || 新拾取.平面距离 <= 当前拾取.平面距离) {
						当前拾取 = 新拾取;
					}
					break;
				}
				case 1: {
					if (新拾取.相交深度 < 当前拾取.相交深度 && 新拾取.平面距离 < 当前拾取.平面距离) {
						当前拾取 = 新拾取;
					}
					break;
				}
				default:
					if (新拾取.相交深度 < 当前拾取.相交深度) {
						当前拾取 = 新拾取;
					}
					break;
			}
			//当前拾取.拾取模式 = 新拾取线模式;
		}
		else {
			都是线拾取 |= 新拾取线模式;
			if (都是线拾取 && 新拾取.平面距离 < 0) {
				return;
			}
			当前拾取 = 新拾取;
		}
	}
	else {
		//当前拾取 = 新拾取;
	}
	return;
}

void f_平行光更新光照信息(void* data) {
	auto 属性 =f_ob_fromParallelLigth(((S_灯光场景数据*)data)->m_灯光);
	f_buf_set(f_buf_getGlobal().m_平行光缓冲区, ((S_灯光场景数据*)data)->m_灯光->m_ID, *属性);

	((S_灯光场景数据*)data)->m_光追后端->f_重置渲染帧记录();

}


void* f_scene_get纹理集(S_Scene* scene) {
	if(scene->m_光追后端) return scene->m_光追后端->f_get纹理(E_纹理分组类型::e_2D纹理);
	return nullptr;
}

uint16 f_scene_get纹理集数量(S_Scene* scene) {
	if (scene->m_光追后端) return scene->m_光追后端->f_get纹理数量(E_纹理分组类型::e_2D纹理);
	return 0;
}

void f_scene_更新光追灯光(S_Scene* scene) {
	std::vector<uint32> 平行光ID;

	for (auto& e : scene->m_灯光) {
		switch (e->m_Type) {
			case E_物体类型::t_区域光: {
				break;
			}
			case E_物体类型::t_平行光: {
				平行光ID.push_back(e->m_ID);
				break;
			}
			case E_物体类型::t_点光源: {
				break;
			}
			case E_物体类型::t_聚光灯: {
				break;
			}
			default:
				break;
		}
	}

	//f_bm_fill()
}



S_渲染世界* f_world_创建渲染世界(S_设备环境& ctx) {
	S_渲染世界* 世界 = new S_渲染世界;
	世界->m_Ctx = ctx;
	世界->m_光追描述集 = nullptr;
	

	世界->m_物体指针 = f_bm_alloc(f_buf_getGlobal().g_UI64缓存, 1);
	世界->m_输出纹理 = f_纹理集_创建();

	世界->m_渲染纹理采样器 = f_tex_创建纹理采样器(ctx);
	世界->m_渲染纹理_最终合成 = f_tex_创建图像纹理(ctx, { 16, 16, 1 }, E_纹理格式::e_tf_RGBA32, E_纹理维度类型::e_2D);
	世界->m_渲染纹理_漫反射 = f_tex_创建图像纹理(ctx, { 16, 16, 1 }, E_纹理格式::e_tf_RGBA32, E_纹理维度类型::e_2D);
	世界->m_渲染纹理_深度 = f_tex_创建图像纹理(ctx, { 16, 16, 1 }, E_纹理格式::e_tf_R32, E_纹理维度类型::e_2D);
	世界->m_渲染纹理_法线 = f_tex_创建图像纹理(ctx, { 16, 16, 1 }, E_纹理格式::e_tf_RGBA32, E_纹理维度类型::e_2D);
	世界->m_渲染纹理_自发光 = f_tex_创建图像纹理(ctx, { 16, 16, 1 }, E_纹理格式::e_tf_RGBA32, E_纹理维度类型::e_2D);
	世界->m_渲染纹理_光照 = f_tex_创建图像纹理(ctx, { 16, 16, 1 }, E_纹理格式::e_tf_R32, E_纹理维度类型::e_2D);

	世界->m_渲染纹理_最终合成->m_TexID = E_RenderLayerType::e_renderLayer_composite;
	世界->m_渲染纹理_漫反射->m_TexID = E_RenderLayerType::e_renderLayer_diffuse;
	世界->m_渲染纹理_深度->m_TexID = E_RenderLayerType::e_renderLayer_depth;
	世界->m_渲染纹理_法线->m_TexID = E_RenderLayerType::e_renderLayer_normal;
	世界->m_渲染纹理_自发光->m_TexID = E_RenderLayerType::e_renderLayer_illuminate;
	世界->m_渲染纹理_光照->m_TexID = E_RenderLayerType::e_renderLayer_shadow;

	f_tex_安装纹理采样器(世界->m_渲染纹理_最终合成, 世界->m_渲染纹理采样器);
	f_tex_安装纹理采样器(世界->m_渲染纹理_漫反射, 世界->m_渲染纹理采样器);
	f_tex_安装纹理采样器(世界->m_渲染纹理_深度, 世界->m_渲染纹理采样器);
	f_tex_安装纹理采样器(世界->m_渲染纹理_法线, 世界->m_渲染纹理采样器);
	f_tex_安装纹理采样器(世界->m_渲染纹理_自发光, 世界->m_渲染纹理采样器);
	f_tex_安装纹理采样器(世界->m_渲染纹理_光照, 世界->m_渲染纹理采样器);

	f_纹理集_add纹理(世界->m_输出纹理, 世界->m_渲染纹理_最终合成);
	f_纹理集_add纹理(世界->m_输出纹理, 世界->m_渲染纹理_漫反射);
	f_纹理集_add纹理(世界->m_输出纹理, 世界->m_渲染纹理_深度);
	f_纹理集_add纹理(世界->m_输出纹理, 世界->m_渲染纹理_法线);
	f_纹理集_add纹理(世界->m_输出纹理, 世界->m_渲染纹理_自发光);
	f_纹理集_add纹理(世界->m_输出纹理, 世界->m_渲染纹理_光照);


	std::vector<vec4> 默认纹理填充(16 * 16);
	f_tex_填充纹理数据(世界->m_渲染纹理_最终合成, (uint8*)默认纹理填充.data(), sizeof(vec4), { 16,16,1 });
	f_tex_填充纹理数据(世界->m_渲染纹理_漫反射, (uint8*)默认纹理填充.data(), sizeof(vec4), { 16,16,1 });
	f_tex_填充纹理数据(世界->m_渲染纹理_深度, (uint8*)默认纹理填充.data(), sizeof(float32), { 16,16,1 });
	f_tex_填充纹理数据(世界->m_渲染纹理_法线, (uint8*)默认纹理填充.data(), sizeof(vec4), { 16,16,1 });
	f_tex_填充纹理数据(世界->m_渲染纹理_自发光, (uint8*)默认纹理填充.data(), sizeof(vec4), { 16,16,1 });
	f_tex_填充纹理数据(世界->m_渲染纹理_光照, (uint8*)默认纹理填充.data(), sizeof(float32), { 16,16,1 });

	世界->m_输出纹理槽 = f_纹理槽_创建(1);

	return 世界;
}

void f_world_销毁渲染世界(S_渲染世界* 世界) {
	for (auto& e : 世界->m_层) {

	}
	if (世界->m_光追描述集) {
		
	}
	f_bm_erase(世界->m_物体指针);

	f_纹理集_销毁(世界->m_输出纹理);

	delete 世界;
}

void f_world_添加渲染层(S_渲染世界* 世界, S_渲染层* 层, uint32 loc) {
	世界->m_层.push_back(层);
	f_bm_resize(世界->m_物体指针, 世界->m_层.size());

	//if (loc >= 世界->m_层.size()) {
	//	世界->m_层.resize(loc + 1);
	//	f_bm_resize(世界->m_物体指针, loc + 1);
	//}
	//
	//世界->m_层[loc] = 层;
}

void f_world_更新绑定(S_渲染世界* 世界) {
	uint32 num = 世界->m_层.size();

	for (uint32 i = 0; i < num; ++i) {
		f_bm_at<uint64>(世界->m_物体指针, i) = f_buf_getAddress2(世界->m_层[i]->m_光追实例物体);
	}

	f_ob_光追加速结构描述集(世界);
}

void f_world_更新输出纹理(S_渲染世界* 世界, uvec2 分辨率, uint32 图层位域) {
	if (图层位域 & (1 << E_RenderLayerType::e_renderLayer_composite))
		f_纹理集_重置纹理大小(世界->m_输出纹理, E_RenderLayerType::e_renderLayer_composite, 分辨率);

	if (图层位域 & (1 << E_RenderLayerType::e_renderLayer_diffuse))
		f_纹理集_重置纹理大小(世界->m_输出纹理, E_RenderLayerType::e_renderLayer_diffuse, 分辨率);

	if (图层位域 & (1 << E_RenderLayerType::e_renderLayer_depth))
		f_纹理集_重置纹理大小(世界->m_输出纹理, E_RenderLayerType::e_renderLayer_depth, 分辨率);

	if (图层位域 & (1 << E_RenderLayerType::e_renderLayer_normal))
		f_纹理集_重置纹理大小(世界->m_输出纹理, E_RenderLayerType::e_renderLayer_normal, 分辨率);

	if (图层位域 & (1 << E_RenderLayerType::e_renderLayer_illuminate))
		f_纹理集_重置纹理大小(世界->m_输出纹理, E_RenderLayerType::e_renderLayer_illuminate, 分辨率);

	if (图层位域 & (1 << E_RenderLayerType::e_renderLayer_shadow))
		f_纹理集_重置纹理大小(世界->m_输出纹理, E_RenderLayerType::e_renderLayer_shadow, 分辨率);
}

void f_world_销毁渲染层(S_渲染世界* 世界, uint32 s, uint32 e) {
	uint32 num = 世界->m_层.size();

	e = min(e, num);
	s = min(s, num);

	for (uint32 i = s; i < e; ++i) {
		f_ob_销毁渲染层(世界->m_层[i]);
	}
	世界->m_层.resize(s);
}



S_渲染参数	f_scene_开始渲染(S_Scene* scene, S_摄像机* camera, const vec2& size, const vec2& offset) {
	scene->m_视口 = { offset.x, offset.y, size.x, size.y, 0.0f, 1.0f };
	scene->m_裁剪 = { _iVec2(offset), uvec2{uint32(size.x), uint32(size.y)} + _uVec2(offset) };

	S_渲染参数 渲染参数{};
	//渲染参数.m_视图投影矩阵 = camera->m_投影矩阵;
	渲染参数.m_视口 = &scene->m_视口;
	渲染参数.m_裁剪 = &scene->m_裁剪;


	if (f_buf_getGlobal().g_全局模型纹理槽.m_槽数量 != 1) {
		f_buf_getGlobal().g_全局模型纹理槽.m_纹理信息 = (void**)realloc(f_buf_getGlobal().g_全局模型纹理槽.m_绑定位置, 1 * sizeof(void*));
		f_buf_getGlobal().g_全局模型纹理槽.m_绑定位置 = (uint32*)realloc(f_buf_getGlobal().g_全局模型纹理槽.m_绑定位置, 1 * sizeof(uint32*));
		f_buf_getGlobal().g_全局模型纹理槽.m_绑定数量 = (uint32*)realloc(f_buf_getGlobal().g_全局模型纹理槽.m_绑定数量, 1 * sizeof(uint32*));

		f_buf_getGlobal().g_全局模型纹理槽.m_槽数量 = 1;
	}

	f_buf_getGlobal().g_全局模型纹理槽.m_纹理信息[0] = f_scene_get纹理集(scene);
	f_buf_getGlobal().g_全局模型纹理槽.m_绑定数量[0] = f_scene_get纹理集数量(scene);
	f_buf_getGlobal().g_全局模型纹理槽.m_绑定位置[0] = DEF_TasterTexturesBindID_rgba8;

	*f_buf_全局GPU参数指针_ptr(f_buf_getGlobal().g_全局绑定参数) = f_df_全局GPU参数();



	return 渲染参数;
}






bool f_scene_光栅渲染(S_Scene* scene) {

	return false;
}



void f_scene_更新变换约束(S_物体* ob) {

}








//void f_scene_构建顶层光追加速结构(S_渲染层* 层, S_OBArray* obs) {
//	if (obs->count) {
//		std::vector<S_GPU内存块*> 光追实例加速结构;
//		光追实例加速结构.reserve(obs->count);
//
//		for (uint32 i = 0; i < obs->count; ++i) {
//			switch (obs->ptr_userData[i]->m_Type) {
//				case E_物体类型::t_多边形:
//				case E_物体类型::t_网格物体: {
//					f_ob_构建光追实例加速结构(obs->ptr_userData[i]);
//					break;
//				}
//			}
//
//			光追实例加速结构.push_back(&(obs->ptr_userData[i]->m_光追实例加速结构));
//		}
//
//		f_df_构建顶层光追加速(层->m_光追顶层加速结构->m_Ctx, 光追实例加速结构, 层->m_光追顶层加速结构);
//	}
//}





			//case E_物体类型::t_区域光_方形:
			//case E_物体类型::t_区域光_圆形:
			//case E_物体类型::t_平行光:
			//case E_物体类型::t_聚光灯:
			//case E_物体类型::t_区域光: {
			//	
			//	mat[0] = 当前矩阵prt[ob->m_实例ID];
			//	mat[1] = *(Mat44f*)&camera.m_相机投影;
			//	mat[2] = *(Mat44f*)&camera.m_相机位置矩阵;
			//	mat[3] = *(Mat44f*)&camera.m_相机逆矩阵;
			//
			//	S_线拾取 拾取信息 = f_surface_屏幕拾取线段(mesh, mat, 屏幕坐标, rect, 28, ob->m_实例ID);
			//
			//
			//	Mat44f 当前变换[2] = {mat[0], mat[1]};
			//	S_摄像机* 摄像机 = dynamic_cast<S_摄像机*>(f_ob_get子对象(ob, 0));
			//	if (摄像机) {
			//		当前变换[0] = mat[0] * f_mat44_构建缩放矩阵(f_camera_计算摄像机以角度缩放大小(摄像机));
			//	}
			//
			//	S_物体拾取信息 新拾取{};
			//
			//	if (mesh->m_间接) {
			//		S_线拾取 拾取信息 = f_surface_线段相交(mesh, 当前变换, s, dir, 当前拾取距离, ob->m_实例ID);
			//
			//		新拾取.相交深度 = 拾取信息.相交点到起点距离;
			//		新拾取.平面距离 = 拾取信息.相交宽度;
			//	}
			//	else {
			//		S_线拾取 拾取信息 = f_surface_线段相交(mesh, 当前变换, s, dir, 当前拾取距离, ob->m_实例ID);
			//
			//		新拾取.相交深度 = 拾取信息.相交点到起点距离;
			//		新拾取.平面距离 = 拾取信息.相交宽度;
			//	}
			//	新拾取.实例ID = ob->m_实例ID;
			//	新拾取.物体 = ob;
			//	新拾取.拾取模式 = 1;
			//	f_scene_对比拾取信息(物体拾取信息, 新拾取, camera.m_投影模式, 1);
			//	break;
			//}

			//case E_物体类型::t_点光源: {
			//	vec3 location = f_ob_get全局坐标(ob, ob->m_实例ID);
			//	距离 = f_graph_点到直线距离(s, dir, location);
			//	if (距离 < vec_Max(ob->m_变换.scale) + 0.1) {
			//		距离 += vec_len(s - location);
			//
			//		物体拾取信息.相交深度 = 距离;
			//		物体拾取信息.实例ID = ob->m_实例ID;
			//		物体拾取信息.物体 = ob;
			//	}
			//	break;
			//}
